<?php
/**
 * 控制器
 *
 * $Id: Controller.class.php 1024 2010-03-23 09:15:21Z sunxy $
 */

require_once(SMARTY_LIB . 'smarty/Smarty.class.php');

class Controller extends Smarty {

	var $application;			// 应用程序名称

	var $document_root;
	var $root;

	var $config_default;		// 缺省配置目录
	var $config_default_file;   // 缺省配置文件

	var $config  = './inc';		// 配置目录
	var $import	 = './lib'; 	// 运行库

	var $template_file;			// 模版文件

	var $version = '1.1';		// 输入页面版本

	/**
	 * 各版本对应模版头输出
	 */
	var $headers = array(
		'0.1'   => 'Content-type:application/vnd.ms-excel',
		'0.2'   => 'Content-type:application/msword',
		'0.3'   => 'Content-type:text/plain',
		'0.4'   => 'Content-type:text/json',
		'1.1'   => 'Content-type:text/vnd.wap.wml;charset=UTF-8',
		'2.0'   => 'Content-type:application/vnd.wap.xhtml+xml;charset=UTF-8',
		'2.1'   => 'Content-type:application/wml+xml;charset=UTF-8',
		'2.2'   => 'Content-type:application/xhtml+xml;charset=UTF-8',
		'4.1'   => 'Content-type:text/html;charset=UTF-8',
		'6.2'   => 'Content-type:text/xml;charset=UTF-8',
		'7.0'   => 'Content-type:text/vnd.sun.j2me.app-descriptor',
	);

	/**
	 * 各版本对应该模版扩展名
	 */
	var $tpls = array(
        '0.1'   => '.tpl',
		'0.2'   => '.tpl',
		'0.3'   => '.tpl',
		'0.4'   => '.tpl',
        '1.1'   => '.wml',
		'2.0'   => '.xhtml',
		'2.1'   => '.xhtml',
		'2.2'   => '.xhtml',
		'4.1'   => '.tpl',
		'6.2'   => '.xml',
		'7.0'   => '.jad',
	);

	function __construct() {
		parent::Smarty();
	}

	/**
	 * 业务处理
	 *
	 * @param array $request
	 * @return boolean 函数的执行结果
	 *
	 * $commandArray[0]为类名 $commandArray[1]为类的方法
	 */
	function execute(&$request) {
		if ($this->pretreat($request)) {
			return true;
		}

		$command = $request['do'];
		$commandArray = explode('.', $command);
		if (count($commandArray) > 1) {
			return $this->clazz($request, $commandArray[0], $commandArray[1]);			
		}

		return false;
	}

	function clazz(&$request, $clazz, $method) {
		$this->import($clazz);

		if (!class_exists($clazz)) {
			return false;
		}

		$commandObject = new $clazz();		
		if (is_callable(array($clazz, $method))) {			
			return $commandObject->$method($this, $request);
		} 

		return $commandObject->layout($this, $request);
	}

	/**
	 * 预处理
	 *
	 * @param array $request
	 */
	function pretreat(&$request) {
		global $cfg;

		if (empty($_SERVER["DOCUMENT_ROOT"])) {
			$this->document_root = APP_LIB . "../";
		} else {
			$this->document_root = $_SERVER["DOCUMENT_ROOT"];
		}
		
		if (is_array($_SERVER) && !empty($_SERVER["SERVER_NAME"])) {
			$root = "http://" . $_SERVER["SERVER_NAME"];
			if ($_SERVER["SERVER_PORT"] <> "80") {
				$root .= ":" . $_SERVER["SERVER_PORT"];
			}
			$root .= $_SERVER["PHP_SELF"];
			$this->root = $root;
			$this->assign('root', $root);
		}

		$command = $request['do'];
		$commandArray = explode('.', $command);
		$clazz = $commandArray[0];

		$this->assign('baseLink', '?do=' . $command);

		if (preg_match("/Post$/i", $command)) {
			$this->assign('postLink', '?do=' . $command);
		} else {
			$this->assign('postLink', '?do=' . $command . "Post");
		}

		$this->assign('findLink', '?do=' . $clazz . ".find");

		$this->assign('addLink', '?do=' . $clazz . ".add");
		$this->assign('editLink', '?do=' . $clazz . ".edit");
		$this->assign('viewLink', '?do=' . $clazz . ".view");
		$this->assign('deleteLink', '?do=' . $clazz . ".delete");
		
		$this->assign('updateLink', '?do=' . $clazz . ".update");
		$this->assign('importLink', '?do=' . $clazz . ".import");
		$this->assign('batchLink', '?do=' . $clazz . ".batch");
		$this->assign('reportLink', '?do=' . $clazz . ".report");

		return false;
	}

	/**
	 * 导入模块，业务处理时调用，在execute()方法中被调用
	 *
	 * @param string $name
	 * @param string $type default 'class'
	 * @return boolean 如lib/MSN.class.php
	 */
	private function import($name, $type = 'class') {
		$file = sprintf("%s.%s.php", $name, $type);
		if (file_exists($this->import . $file)) {
			require_once($this->import . $file);
			return true;
		}

		$file = sprintf("common/%s.%s.php", $name, $type);
		if (file_exists(APP_LIB . $file)) {
			require_once(APP_LIB . $file);
			return true;
		}
		
		return false;
	}

	/**
	 * 页面显示
	 *
	 * @param array $request
	 * @param string $resource_name 如chat
	 * @param string $cache_id
	 * @param string $compile_id
	 */
	function display(&$request, $resource_name, $cache_id = null, $compile_id = null) {
		if (!$this->load_tpl($request, $resource_name)) {
			return false;
		}

		// $this->load_cfg($resource_name);

		$this->head();

		parent::display($this->template_file, $cache_id, $compile_id);
	}
	
	function sunxy(&$request, $resource_name, $cache_id = null, $compile_id = null) {
		if (!$this->load_tpl($request, $resource_name)) {
			return false;
		}

		$this->head();
		// echo $this->template_file;

		return parent::fetch($this->template_file, $cache_id, $compile_id);
	}

	/**
	 * 输出头信息
	 */
	private function head() {
		@header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

		// @header("Content-Disposition: attachment; filename=aa.doc");

		@header("Cache-Control: no-cache, must-revalidate");
		@header("Pragma: no-cache");
		@header($this->headers[$this->version]);
	}

	/**
	 * 加载配置信息
	 */
	private function load_cfg($resource_name) {
		$this->config_dir = $this->config;

		$config_file = sprintf("%s%s", $this->application, '_g.cfg');
		// echo $this->config . '/' . $config_file;
		if (file_exists($this->config . '/' . $config_file)) {
			$this->config_load($config_file);
		}

		$config_file = sprintf("%s%s", $this->application, '_m.cfg');

		// echo $this->config_dir . '/' . $config_file;
		if (file_exists($this->config_dir . '/' . $config_file)) {
			$this->config_load($config_file, $resource_name);

			$title = $this->get_config_vars('title');
			if (!isset($title) || strlen($title) == 0) {
				$this->load_cfg_default($resource_name);
			}
		} else {
			$this->load_cfg_default($resource_name);
		}
	}

	/**
	 * 装载模块配置参数
	 *
	 * @param string $resource_name
	 */
	private function load_cfg_default($resource_name) {
		if (empty($this->config_default)) {
			return false;
		}

		$this->config_dir = $this->config_default;
		if (empty($this->config_default_file)) {
			$config_file = sprintf("%s%s", $this->application, '_m.cfg');
		} else {
			$config_file = $this->config_default_file;
		}

		// echo $this->config_dir . '/' . $config_file;
		if (file_exists($this->config_dir . '/' . $config_file)) {
			@$this->config_load($config_file, $resource_name);
			return true;
		}

		return false;
	}

	/**
	 * 计算模版
	 *
	 * @param array $request
	 * @param string $resource_name
	 */
	private function load_tpl(&$request, $resource_name) {
		global $skins;
		// debug(print_r($request, true));

		// $skins = $cfg['skins'];
		if (isset($request['tpl'])) {
			$skin = $skins[$request['tpl']];
			if ($this->tpl($request, $resource_name, $skin)) {
				return true;
			}
		}

		if (empty($request['tpl_'])) {
			return false;
		}

		$skin = $skins[$request['tpl_']];
		$this->tpl($request, $resource_name, $skin);
		return true;
	}

	/**
	 * 计算模版文件及编译目录
	 *
	 * @param array $request
	 * @param string $resource_name
	 */
	private function tpl(&$request, $resource_name, $skin) {
		$this->template_dir = $this->document_root . $skin['tpl_dir'] . $skin['tpl'];
		$template_file = sprintf("%s%s", $resource_name, $this->tpls[$skin['version']]);

		// echo $this->template_dir . "/" . $template_file;
		if (file_exists($this->template_dir . "/" . $template_file)) {
			$this->template_file = $template_file;
			$this->tpl_c($request, $resource_name, $skin);
			return true;
		}

		$this->template_dir = $this->document_root . "/tpl/" . $skin['tpl'];
		$template_file = sprintf("%s%s", $resource_name, $this->tpls[$skin['version']]);

		// echo $this->template_dir . "/" . $template_file;
		if (file_exists($this->template_dir . "/" . $template_file)) {
			$this->template_file = $template_file;
			$this->tpl_c($request, $resource_name, $skin);
			return true;
		}

		return false;
	}

	/**
	 * 计算编译目录
	 *
	 * @param array $request
	 * @param array $skin
	 */
	private function tpl_c(&$request, $resource_name, $skin) {
		$pos = strrpos($resource_name, "/");
		$subdir = substr($resource_name, 0, $pos);

		$s = $this->document_root . "/../compile/" . $_SERVER["SERVER_NAME"] . "/";

		if (empty($request['cpl_dir'])) {
			$template_c = $s . $skin['tpl_dir'] . $skin['tpl'] . "/" . $subdir;
		} else {
			$template_c = $s . $request['cpl_dir'] . $skin['tpl'] . "/" . $subdir;
		}

		// echo $template_c;
		
		if (!@file_exists($template_c)) {
			//@exec ("mkdir -p " . $template_c);
			umask();
			mkdir($template_c, 0777, true);
		}
		
		$this->compile_dir = $template_c;
		$this->version = $skin['version'];

		$this->cache($request, $resource_name, $skin);
	}

	/**
	 * 计算缓存目录
	 *
	 * @param array $request
	 * @param array $skin
	 */
	private function cache(&$request, $resource_name, $skin) {
		if (!$this->caching) {
			return false;
		}

		$pos = strrpos($resource_name, "/");
		$subdir = substr($resource_name, 0, $pos);

		$s = $this->document_root . "/../cache/";

		if (empty($request['cpl_dir'])) {
			$cache = $s . $skin['tpl_dir'] . $skin['tpl'] . "/" . $subdir;
		} else {
			$cache = $s . $request['cpl_dir'] . $skin['tpl'] . "/" . $subdir;
		}
		
		// echo $cache;
		
		if (!@file_exists($cache)) {
			//@exec ("mkdir -p " . $cache);
			umask();
			mkdir($cache, 0777, true);
		}

		$this->cache_dir = $cache;
	}
}
?>
